package com.lebang.service.cences;

import com.lebang.domain.CencesApru;
import com.lebang.domain.CencesStoreData;
import com.lebang.domain.DownloadMemberRecord;
import com.lebang.example.CencesStoreDataExample;
import com.lebang.mapper.*;
import com.lebang.model.MyConfig;
import com.lebang.model.Whether;
import com.lebang.model.back.ImeiRegister;
import com.lebang.model.cences.CencesMsg;
import com.lebang.model.cences.TotalCount;
import com.lebang.model.enums.buss.TaskCategory;
import com.lebang.service.BaseService;
import com.lebang.service.mongodb.CencesMsgMongodb;
import com.lebang.service.mongodb.ImeiRegisterMongodb;
import com.lebangweb.common.TextUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * 新手任务
 *
 * @Author hwq
 * @Date 2020-02-06
 */
@Service
@Slf4j
public class CencesEarnDataService extends BaseService<CencesStoreData, Integer, CencesStoreDataExample> {
    @Autowired
    private CencesStoreDataMapper baseMapper;
    @Autowired
    private LbbMemberMapper lbbMemberMapper;
    @Autowired
    private TaskRouseMapper taskRouseMapper;
    @Autowired
    private MemberNewTradeMapper memberNewTradeMapper;
    @Autowired
    private CencesApruMapper apruMapper;
    @Autowired
    private DownloadMemberRecordMapper recordMapper;
    @Autowired
    private CencesMsgMongodb cencesMsgMongodb;
    @Autowired
    private ImeiRegisterMongodb imeiRegisterMongodb;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private DownloadMemberRecordMapper downloadMemberRecordMapper;

    public int deleteByTime(int time) {
        CencesStoreDataExample earnDayExample = new CencesStoreDataExample();
        earnDayExample.createCriteria().andTimeEqualTo(time).andAppIdEqualTo(MyConfig.getEnv());
        return baseMapper.deleteByExample(earnDayExample);
    }

    ;

    public void starDataInit(LocalDateTime end) {
        this.starDataInit(end, null);
    }

    public void starDataInit(LocalDateTime end, List<String> brand) {
        long starTime = System.currentTimeMillis();
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMdd");
        LocalDateTime star = end.minusDays(1);
        LocalDate starDate = star.toLocalDate();
        int time = Integer.parseInt(end.toLocalDate().minusDays(1).format(df));
        List<CencesStoreData> cencesMasters = new ArrayList<>();
        if (brand == null) {
            brand = lbbMemberMapper.selectBrand();
        }

        List<DownloadMemberRecord> all = recordMapper.selectNewMemberByTime(star, end);

        //根据渠道统计新增设备
        Query query = new Query();
        Criteria criteria = new Criteria();
        //设置查询时间范围
        if (!TextUtil.isEmpty(star)) {
            criteria.and("createDateTime").gte(star).lte(end);
        }
        query.addCriteria(criteria);
        //新增设备
        List<ImeiRegister> mongoVehicleUploadLogs = mongoTemplate.find(query, ImeiRegister.class);
        Map<String, List<ImeiRegister>> imeiMap = mongoVehicleUploadLogs.stream().collect(Collectors.groupingBy(ImeiRegister::getAppStore));
        //新增注册
        List<CencesApru> list = apruMapper.selectBrandCount(star, end);
        Map<String, List<CencesApru>> resigister = list.stream().collect(Collectors.groupingBy(CencesApru::getBrand));
        Map<String, List<DownloadMemberRecord>> storeMap = all.stream().collect(Collectors.groupingBy(DownloadMemberRecord::getAppStore));
        //全部用户的

        brand.forEach(s -> {
            CencesStoreData allVo = new CencesStoreData(0, s, time,MyConfig.getEnv());
            allVo.setNewMember(this.sumBy(resigister, s));
            allVo.setNewResigiter(this.sumByImei(imeiMap, s));
            allVo.setNewEarnCount(this.sumByCount(storeMap, s));
            allVo.setNewEarnOnlyCount(this.sumByOnlyCount(storeMap, s));
            allVo.setModifyTime(LocalDateTime.now());
            allVo.setHasDeleted(0);
            cencesMasters.add(allVo);
            baseMapper.insertAll(allVo);
        });
        CencesStoreData data = new CencesStoreData(0, "all", time,MyConfig.getEnv());
        data.setNewMember(0);
        data.setNewResigiter(0);
        data.setNewEarnCount(0);
        data.setNewEarnOnlyCount(0);
        data.setModifyTime(LocalDateTime.now());
        data.setHasDeleted(0);
        cencesMasters.forEach(s -> {
            sumByD(s, data);
        });
        baseMapper.insertAll(data);
        cencesMsgMongodb.save(new CencesMsg("渠道每日必赚分析", System.currentTimeMillis() - starTime));
    }


    public CencesStoreData sumData(Integer star, Integer end, String appStore, int category, int type, String likeBrand) {
        return baseMapper.sumData(star, end, appStore, category, type,likeBrand,MyConfig.getEnv());
    }

    private void sumByD(CencesStoreData vo, CencesStoreData data) {
        data.setNewMember(data.getNewMember()+vo.getNewMember());
        data.setNewResigiter(data.getNewResigiter()+vo.getNewResigiter());
        data.setNewEarnCount(data.getNewEarnCount()+vo.getNewEarnCount());
        data.setNewEarnOnlyCount(data.getNewEarnOnlyCount()+vo.getNewEarnOnlyCount());

    }

    private int sumBy(Map<String, List<CencesApru>> resigister, String appStore) {
        AtomicInteger atomicInteger = new AtomicInteger(0);
        List<CencesApru> list = resigister.get(appStore);
        if (list != null) {
            list.forEach(s -> atomicInteger.addAndGet(s.getResisterMemberCount()));
        }
        return atomicInteger.get();
    }

    private int sumByImei(Map<String, List<ImeiRegister>> resigister, String appStore) {
        AtomicInteger atomicInteger = new AtomicInteger(0);
        List<ImeiRegister> list = resigister.get(appStore);
        if (list != null) {
            return list.size();
        }
        return atomicInteger.get();
    }

    private int sumByCount(Map<String, List<DownloadMemberRecord>> resigister, String appStore) {
        AtomicInteger atomicInteger = new AtomicInteger(0);
        List<DownloadMemberRecord> list = resigister.get(appStore);
        if (list != null) {
            return list.size();
        }
        return atomicInteger.get();
    }

    private int sumByOnlyCount(Map<String, List<DownloadMemberRecord>> resigister, String appStore) {
        AtomicInteger atomicInteger = new AtomicInteger(0);
        List<DownloadMemberRecord> list = resigister.get(appStore);
        if (list != null) {
            Map<String, List<DownloadMemberRecord>> on = list.stream().collect(Collectors.groupingBy(DownloadMemberRecord::getMemberId));
            return on.size();
        }
        return atomicInteger.get();
    }

    public TotalCount selectData(LocalDateTime star, LocalDateTime end, String appStore, int count, int between) {
        TotalCount totalCount = new TotalCount();
        int newCount = memberNewTradeMapper.countByCategoryGroupByMemberIdEarn(star, end, appStore, Whether.YES.getDbIndex(), count, TaskCategory.CSJ_ZXR.name());
        int oldCount = memberNewTradeMapper.countByCategoryGroupByMemberIdEarn(star, end, appStore, Whether.NO.getDbIndex(), count, TaskCategory.CSJ_ZXR.name());
        int allCount = newCount + oldCount;

        int betweennewCount = memberNewTradeMapper.countByCategoryGroupByMemberIdEarn(star.minusDays(between), end.minusDays(between), appStore, Whether.YES.getDbIndex(), count, TaskCategory.CSJ_ZXR.name());
        int betweenoldCount = memberNewTradeMapper.countByCategoryGroupByMemberIdEarn(star.minusDays(between), end.minusDays(between), appStore, Whether.NO.getDbIndex(), count, TaskCategory.CSJ_ZXR.name());
        int betweenallCount = betweennewCount + betweenoldCount;

        totalCount.setBetweenNewTotal(betweennewCount);
        totalCount.setBetweenOldTotal(betweenoldCount);
        totalCount.setBetweenTotal(betweenallCount);
        totalCount.setNewTotal(newCount);
        totalCount.setOldTotal(oldCount);
        totalCount.setTotal(allCount);
        totalCount.setCount(count);
        return totalCount;
    }


}
